package com.insight.controller;

import com.insight.common.enums.CollectionType;
import com.insight.common.enums.TaskStatus;
import com.insight.dto.collection.CollectionTaskCreateRequest;
import com.insight.dto.collection.CollectionTaskResponse;
import com.insight.entity.CollectionTask;
import com.insight.entity.DataSource;
import com.insight.service.CollectionTaskService;
import com.insight.service.DataSourceService;
import com.insight.service.MetadataCollectionService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

import java.util.HashMap;
import java.util.Map;

/**
 * T074: 采集任务控制器
 * 提供元数据采集任务的REST API
 *
 * @author Insight Team
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/collections")
@RequiredArgsConstructor
public class CollectionController {

    private final CollectionTaskService collectionTaskService;
    private final DataSourceService dataSourceService;
    private final MetadataCollectionService metadataCollectionService;

    /**
     * 创建采集任务
     *
     * @param request 创建请求
     * @return 任务响应
     */
    @PostMapping
    public ResponseEntity<CollectionTaskResponse> createCollectionTask(
            @Valid @RequestBody CollectionTaskCreateRequest request) {

        log.info("创建采集任务: datasourceId={}, type={}", request.getDatasourceId(), request.getType());

        // 1. 验证数据源存在
        DataSource dataSource = dataSourceService.findById(request.getDatasourceId())
                .orElseThrow(() -> new ResponseStatusException(
                        HttpStatus.NOT_FOUND,
                        "数据源不存在: id=" + request.getDatasourceId()
                ));

        // 2. 创建任务
        CollectionTask task = collectionTaskService.createTask(dataSource, request.getType());

        // 3. 异步执行采集(不阻塞HTTP响应)
        // TODO: 在T076完成后集成Kafka事件发布
        // 当前先异步调用采集服务
        /*
        CompletableFuture.runAsync(() -> {
            try {
                if (request.getType() == CollectionType.FULL) {
                    metadataCollectionService.collectFullMetadata(dataSource, extractor);
                } else {
                    metadataCollectionService.collectIncrementalMetadata(dataSource, extractor);
                }
            } catch (Exception e) {
                log.error("采集任务执行失败: taskId={}", task.getId(), e);
            }
        });
        */

        log.info("采集任务创建成功: taskId={}", task.getId());

        // 4. 返回响应
        return ResponseEntity
                .status(HttpStatus.CREATED)
                .body(toResponse(task));
    }

    /**
     * 获取任务详情
     *
     * @param id 任务ID
     * @return 任务响应
     */
    @GetMapping("/{id}")
    public ResponseEntity<CollectionTaskResponse> getCollectionTask(@PathVariable Long id) {
        log.debug("查询采集任务: id={}", id);

        CollectionTask task = collectionTaskService.findById(id)
                .orElseThrow(() -> new ResponseStatusException(
                        HttpStatus.NOT_FOUND,
                        "采集任务不存在: id=" + id
                ));

        return ResponseEntity.ok(toResponse(task));
    }

    /**
     * 取消采集任务
     *
     * @param id 任务ID
     * @return 无内容响应
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> cancelCollectionTask(@PathVariable Long id) {
        log.info("取消采集任务: id={}", id);

        // 1. 验证任务存在
        CollectionTask task = collectionTaskService.findById(id)
                .orElseThrow(() -> new ResponseStatusException(
                        HttpStatus.NOT_FOUND,
                        "采集任务不存在: id=" + id
                ));

        // 2. 验证任务状态可取消
        if (task.getStatus() != TaskStatus.PENDING && task.getStatus() != TaskStatus.RUNNING) {
            throw new ResponseStatusException(
                    HttpStatus.CONFLICT,
                    "任务状态不允许取消: status=" + task.getStatus()
            );
        }

        // 3. 取消任务
        collectionTaskService.cancelTask(id);

        log.info("采集任务取消成功: id={}", id);

        return ResponseEntity.noContent().build();
    }

    /**
     * 分页查询任务列表
     *
     * @param datasourceId 数据源ID筛选(可选)
     * @param status       任务状态筛选(可选)
     * @param type         任务类型筛选(可选)
     * @param pageable     分页参数
     * @return 任务列表
     */
    @GetMapping
    public ResponseEntity<Page<CollectionTaskResponse>> listCollectionTasks(
            @RequestParam(required = false) Long datasourceId,
            @RequestParam(required = false) TaskStatus status,
            @RequestParam(required = false) CollectionType type,
            @PageableDefault(size = 20, sort = "createdAt") Pageable pageable) {

        log.debug("查询采集任务列表: datasourceId={}, status={}, type={}, page={}",
                datasourceId, status, type, pageable.getPageNumber());

        Page<CollectionTask> tasks;

        if (datasourceId != null) {
            tasks = collectionTaskService.findByDataSource(datasourceId, pageable);
        } else if (status != null) {
            tasks = collectionTaskService.findByStatus(status, pageable);
        } else if (type != null) {
            tasks = collectionTaskService.findByType(type, pageable);
        } else {
            tasks = collectionTaskService.findAll(pageable);
        }

        Page<CollectionTaskResponse> response = tasks.map(this::toResponse);

        return ResponseEntity.ok(response);
    }

    /**
     * 将实体转换为响应DTO
     *
     * @param task 采集任务实体
     * @return 响应DTO
     */
    private CollectionTaskResponse toResponse(CollectionTask task) {
        return CollectionTaskResponse.builder()
                .id(task.getId())
                .datasourceId(task.getDataSource().getId())
                .datasourceName(task.getDataSource().getName())
                .type(task.getCollectionType())
                .status(task.getStatus())
                .startTime(task.getStartTime())
                .endTime(task.getEndTime())
                .totalTables(task.getTablesTotal())
                .completedTables(task.getTablesCollected())
                .errorMessage(task.getErrorMessage())
                .createdAt(task.getCreatedAt())
                .updatedAt(task.getUpdatedAt())
                .build();
    }

    /**
     * 全局异常处理 - 数据源不存在
     */
    @ExceptionHandler(ResponseStatusException.class)
    public ResponseEntity<Map<String, Object>> handleResponseStatusException(ResponseStatusException ex) {
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("status", ex.getStatusCode().value());
        errorResponse.put("message", ex.getReason());
        errorResponse.put("timestamp", System.currentTimeMillis());

        return ResponseEntity
                .status(ex.getStatusCode())
                .body(errorResponse);
    }
}
